from odoo.http import request, Response
from odoo import http, Command
from odoo.addons.api_manager.tools.check_token import check_token
from odoo.addons.api_manager.tools.create_records import create_records
import logging
import json
from odoo import fields, _
from odoo.exceptions import ValidationError

_logger = logging.getLogger(__name__)


class ApiRefundScrap(http.Controller):

    @http.route("/v1.0/sb_api/return/scrap", auth='public', type='http', methods=['post'], csrf=False)
    @check_token
    def mrp_return_scrap(self, **kwargs):
        """退报废，退回到报废工序，再自动过数到当前工序
        {
            'jsonrpc': 2.0,
            'token': xxx,
            'params': {
                'production_code': '',
                'workorder_code': '',
                'workcenter_code': '',
                'qty_reject_pnl': '',
                'qty_reject_set': '',
                'qty_reject_pcs': '',
                ''
                'note': '',
                'note_01': '',
                'note_02': '',
                'note_03': '',
            }
        }
        """
        _logger.info('开始成品入库请求...')
        request.env.uid = 2
        data = request.httprequest.get_json()
        result = {
            'json': True,
            'data': {}
        }
        api_result = {
            'code': 0,
            'message': 'success'
        }
        params = data.get('params')
        # public user，无法操作，使用admin
        request.env.uid = 2
        try:
            production_code = params.get('production_code', False)
            workorder_code = params.get('workorder_code', False)
            mes_code = params.get('mes_code', False)
            if not mes_code:
                raise ValidationError('mes_code, 不能为空')
            workorder = self.get_workorder(production_code, workorder_code)
            if not workorder:
                raise ValidationError('未找到对应工序workorder_code: {}'.format(workorder_code))
            if not workorder.s_scrap_ids:
                raise ValidationError('工序：{}, 没有报废申请'.format(workorder_code))
            if workorder.production_id.state == 'done':
                raise ValidationError('当前制造单已完成，不支持退报废')

            alert = request.env['quality.alert'].search([('s_mes_code', '=', mes_code)])
            if not alert:
                raise ValidationError('mes_code: {} 未找到'.format(mes_code))
            if len(alert) > 1:
                raise ValidationError('mes_code: {} 不唯一'.format(mes_code))
            logstr = ''
            # 01 处理退报废
            scrap_workcenters = params.get('scrap_workcenters', [])
            workcenter_ids = []
            workorder_dict = {'qty_produced': 0, 'qty_produced_pnl': 0, 'qty_produced_set': 0, 'user_id': request.env.uid}
            for s in scrap_workcenters:
                workcenter_code = s.get('workcenter_code', False)
                if not workcenter_code or not workorder_code or not production_code:
                    raise ValidationError(_('production_code、workorder_code、workcenter_code 不能为空'))
                workcenter = request.env['mrp.workcenter'].sudo().search([('code', '=', workcenter_code)])
                if not workcenter:
                    raise ValidationError('未找到对应的责任工序， workcenter_code：{}'.format(workcenter_code))
                workcenter_ids.append(workcenter.id)
                qty_reject_pnl = s.get('qty_reject_pnl', False)
                qty_reject_set = s.get('qty_reject_set', False)
                qty_reject_pcs = s.get('qty_reject_pcs', False)
                if not qty_reject_pcs:
                    raise ValidationError(_('qty_reject_pcs 不能为空'))
                scrap_vals = {
                    'workorder_id': workorder.id,
                    'scrap_workcenter_id': workcenter.id,
                    'note': params.get('note', ''),
                    'scrap_qty': qty_reject_pcs,
                    'scrap_set_qty': qty_reject_set,
                    'scrap_panel_qty': qty_reject_pnl
                }
                if workorder.state == 'done':
                    # 退报废明细
                    scrap_vals['quality_alert_id'] = alert.id
                    request.env['s.workorder.return.scrap.record'].create(scrap_vals)
                else:
                    # 退报废明细
                    request.env['s.workorder.return.scrap.record'].create(scrap_vals)
                workorder_dict['qty_produced'] += qty_reject_pcs
                workorder_dict['qty_produced_pnl'] += qty_reject_pnl
                workorder_dict['qty_produced_set'] += qty_reject_set
            # 02 断开工序和报废明细关系，保留历史记录
            for s_scrap in alert.s_scrap_ids:
                if s_scrap.scrap_workcenter_id.id in workcenter_ids:
                    s_scrap.workorder_id = None
            alert.description = "MES接口退报废，具体信息请查看退报废明细"
            alert.s_is_return = True

            # 03 重新计算已完成的工序数
            if workorder.state == 'done':
                # 大于等于当前工序，新增完成记录，数量=退报废数量
                update_wo = workorder.production_id.workorder_ids.filtered(lambda x: x.state=='done' and x.step >= workorder.step)
                process_wo = workorder.production_id.workorder_ids.filtered(lambda x: x.state=='progress' and x.step > workorder.step)
                # update_wo.write({'done_line_ids': })
                # for a_wo in after_wo:
                #     a_wo.update({
                #         'done_line_ids': [(0, 0, {
                #             'qty_produced': qty_reject_pcs,
                #             'qty_produced_pnl': qty_reject_pnl,
                #             'qty_produced_set': qty_reject_set,
                #             'user_id': request.env.uid})]
                #     })

                # 重新计算完成数
                for a_wo in update_wo:
                    qty_op_reject = (
                            sum(a_wo.done_line_ids.mapped('qty_reject')) +
                            sum(a_wo.s_scrap_ids.mapped('scrap_qty'))
                    )
                    qty_op_reject_set = (
                            sum(a_wo.done_line_ids.mapped('qty_reject_set')) +
                            sum(a_wo.s_scrap_ids.mapped('scrap_set_qty'))
                    )
                    qty_op_reject_pnl = (
                            sum(a_wo.done_line_ids.mapped('qty_reject_pnl')) +
                            sum(a_wo.s_scrap_ids.mapped('scrap_panel_qty'))
                    )
                    qty_op_produced = sum(a_wo.done_line_ids.mapped('qty_produced')) + workorder_dict['qty_produced']
                    qty_op_produced_set = sum(a_wo.done_line_ids.mapped('qty_produced_set')) + workorder_dict['qty_produced_set']
                    qty_op_produced_pnl = sum(a_wo.done_line_ids.mapped('qty_produced_pnl')) + workorder_dict['qty_produced_pnl']
                    update_dict = {
                        'done_line_ids': [(0, 0, workorder_dict)],
                        'done_act_qty': qty_op_produced,
                        'qty_op_produced': qty_op_produced,
                        'qty_op_produced_set': qty_op_produced_set,
                        'qty_op_produced_pnl': qty_op_produced_pnl,
                        'qty_op_reject': qty_op_reject,
                        'qty_op_reject_set': qty_op_reject_set,
                        'qty_op_reject_pnl': qty_op_reject_pnl
                    }
                    a_wo.update(update_dict)
                    logstr += a_wo.display_name
                    logstr += str(update_dict)
                    logstr += '===分割线==='

                # 重新计算在制数
                if process_wo:
                    process_wo.state = 'ready'
                    process_wo.button_pending()
                    process_wo.button_start()

        except Exception as e:
            api_result['message'] = '{}'.format(e)
            api_result['code'] = -1
            request.env.cr.rollback()
        api_result['logstr'] = logstr
        result['data'] = api_result
        result_json = json.dumps(result, ensure_ascii=False)
        create_records(result_json)
        return Response(result_json)

    def get_workorder(self, production_code, workorder_code):
        sql = """
                SELECT mw.id FROM mrp_workorder as mw, mrp_production as mp, mrp_workcenter as mc  
                WHERE mw.production_id=mp.id
                and mw.workcenter_id=mc.id
                and mp.name='{}'
                and mc.code='{}';
            """.format(production_code, workorder_code)
        cr = request.env.cr
        cr.execute(sql)
        wid = cr.fetchall()
        if not wid:
            raise ValidationError('未查询到相关工序: {}-{}'.format(production_code, workorder_code))
        if len(wid) > 1:
            raise ValidationError('查询到工序不唯一：{}-{}'.format(production_code, workorder_code))
        wo = request.env['mrp.workorder'].sudo().search([('id', '=', list(wid[0])[0])])
        return wo
